package org.backend.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.backend.AnnotationProcessor;
import org.backend.pojo.entity.User;
import org.backend.pojo.entity.WxUser;
import org.backend.exception.LoginFailedException;
import org.backend.pojo.dto.WxUserLoginDTO;
import org.backend.pojo.vo.LoginResponseVO;
import org.backend.pojo.vo.WxUserInfoVO;
import org.backend.properties.WeChatProperties;
import org.backend.repository.UserRepository;
import org.backend.service.UserService;
import org.backend.utils.ApiResponse;
import org.backend.utils.HttpClientUtil;
import org.backend.utils.JwtUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    // 微信服务接口地址
    public static final String WX_LOGIN = "http://api.weixin.qq.com/sns/jscode2session";

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private WeChatProperties weChatProperties;

    @Override
    public LoginResponseVO login(String account, String password) {
        // 根据账号查询用户信息
        User user = userRepository.findUserByAccount(account);
        LoginResponseVO loginResponse = new LoginResponseVO();
        // 用户不存在或密码不匹配
        if (user == null || !user.getPassword().equals(password)) {
            return null;
        }

        // 生成 JWT 令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getUserId());
        claims.put("username", user.getUsername());

        String jwt = JwtUtil.generateToken(claims);

        // 验证通过，设置返回信息
        loginResponse.setUsername(user.getUsername());
        loginResponse.setUserId(user.getUserId());
        loginResponse.setPhone(user.getPhone());
        loginResponse.setEmail(user.getEmail());
        loginResponse.setAvatar(user.getAvatar());
        loginResponse.setToken(jwt);

        return loginResponse;
    }

    @Override
    public ApiResponse<String> register(User user) {
        try {
            userRepository.insertUser(user);
            return ApiResponse.success("用户注册成功");
        } catch (DuplicateKeyException e) {
            System.out.println(e.getMessage());
            if (e.getMessage().contains("users.unique_email")) {
                return ApiResponse.error(401, "用户身份验证过期，请重新登录");
            } else if (e.getMessage().contains("users.account")) {
                return ApiResponse.error(402, "账号" + user.getAccount() + " 已存在");
            } else if (e.getMessage().contains("users.unique_email")) {
                return ApiResponse.error(403, "邮箱" + user.getEmail() + " 已存在");
            }
            return ApiResponse.error("注册失败，系统错误：" + e.getMessage());
        } catch (Exception e) {
            return ApiResponse.error("注册失败，系统错误: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<String> saveUserInfo(User user) {
        int rows = userRepository.saveUserInfo(user);
        if (rows == 0) {
            return ApiResponse.error("保存失败");
        }
        return ApiResponse.success("保存成功");
    }

    @Override
    public WxUser wxLogin(WxUserLoginDTO wxUserLoginDTO) {
        String openid = getOpenid(wxUserLoginDTO.getCode());

        if (openid == null) {
            throw new LoginFailedException("登录失败");
        }

        // 判断当前用户是否为新用户
        WxUser wxUser = userRepository.getByOpenid(openid);

        // 如果是新用户，自动完成注册
        if (wxUser == null) {
            wxUser = wxUser.builder()
                    .openid(openid)
                    .createTime(LocalDateTime.now())
                    .build();
            userRepository.insertWxUser(wxUser);
        }

        return wxUser;
    }

    @Override
    public ApiResponse<WxUserInfoVO> getWxUserInfo(String openId) {
        WxUser wxUser = userRepository.findWxUserByOpenId(openId);
        try {
            AnnotationProcessor.validate(wxUser);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

        WxUserInfoVO wxUserInfoVO = new WxUserInfoVO();
        BeanUtils.copyProperties(wxUser, wxUserInfoVO);
        log.info("wxUserInfoVO: {}", JSON.toJSONString(wxUserInfoVO));
        return ApiResponse.success(wxUserInfoVO);
    }

    @Override
    public ApiResponse<String> editWxUserInfo(WxUserInfoVO wxUserInfoVO) {
        WxUser wxUser = new WxUser();
        BeanUtils.copyProperties(wxUserInfoVO, wxUser);
        if (userRepository.editWxUserInfo(wxUser) > 0) {
            return ApiResponse.success("修改成功");
        }
        return ApiResponse.error("修改失败");
    }

    /**
     * 调用微信接口服务在登录时获取openid
     *
     * @param code
     * @return
     */
    private String getOpenid(String code) {
        // 调用微信接口服务，获取当前微信用户的openid
        Map<String, String> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        String json = HttpClientUtil.doGet(WX_LOGIN, map);

        JSONObject jsonObject = JSON.parseObject(json);
        String openid = jsonObject.getString("openid");
        log.info("获取到的openid为:{}", openid);
        return openid;
    }
}
